package com.hitomi.refresh.view;

import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorGroup;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.DependentLayout;
import ohos.agp.components.StackLayout;
import ohos.agp.components.Text;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.Color;
import ohos.agp.utils.TextAlignment;
import ohos.app.Context;

/**
 * Created by Hitomis on 2016/3/1.
 */
public class FunGameHeader extends StackLayout implements Component.EstimateSizeListener {
    private static final int DEFAULT_TEXT_SIZE = 35;

    private Context mContext;

    private int headerType;

    private FunGameView funGameView;

    private DependentLayout curtainReLayout;

    private DependentLayout maskReLayout;

    private Text topMaskView;

    private Text bottomMaskView;

    private int halfHitBlockHeight;

    private boolean isStart = false;

    private String topMaskViewText = "Pull To Break Out!";
    private String bottomMaskViewText = "Scrooll to move handle";
    private String loadingText = "Loading...";
    private String loadingFinishedText = "Loading Finished";
    private String gameOverText = "Game Over";

    private int topMaskTextSize = DEFAULT_TEXT_SIZE;

    private int bottomMaskTextSize = DEFAULT_TEXT_SIZE;


    public FunGameHeader(Context context) {
        this(context, null);
    }

    public FunGameHeader(Context context, AttrSet attrSet) {
        this(context, attrSet, null);
    }

    public FunGameHeader(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        mContext = context;
        if (attrSet != null && attrSet.getAttr(Styleable.GAME_TYPE).isPresent()) {
            headerType = attrSet.getAttr(Styleable.GAME_TYPE).get().getIntegerValue();
        } else {
            headerType = FunGameFactory.HITBLOCK;
        }
        if (attrSet != null) {
            if (attrSet.getAttr(Styleable.MASK_TOP_TEXT).isPresent()) {
                topMaskViewText = attrSet.getAttr(Styleable.MASK_TOP_TEXT).get().getStringValue();
            }
            if (attrSet.getAttr(Styleable.MASK_BOTTOM_TEXT).isPresent()) {
                bottomMaskViewText = attrSet.getAttr(Styleable.MASK_BOTTOM_TEXT).get().getStringValue();
            }
            if (attrSet.getAttr(Styleable.TEXT_LOADING).isPresent()) {
                loadingText = attrSet.getAttr(Styleable.TEXT_LOADING).get().getStringValue();
            }
            if (attrSet.getAttr(Styleable.TEXT_LOADING_FINISHED).isPresent()) {
                loadingFinishedText = attrSet.getAttr(Styleable.TEXT_LOADING_FINISHED).get().getStringValue();
            }
            if (attrSet.getAttr(Styleable.TEXT_GAME_OVER).isPresent()) {
                gameOverText = attrSet.getAttr(Styleable.TEXT_GAME_OVER).get().getStringValue();
            }
            if (attrSet.getAttr(Styleable.TOP_TEXT_SIZE).isPresent()) {
                topMaskTextSize = attrSet.getAttr(Styleable.TOP_TEXT_SIZE).get().getDimensionValue();
            }
            if (attrSet.getAttr(Styleable.BOTTOM_TEXT_SIZE).isPresent()) {
                bottomMaskTextSize = attrSet.getAttr(Styleable.BOTTOM_TEXT_SIZE).get().getDimensionValue();
            }
        }
        initView(attrSet);
    }


    private void initView(AttrSet attrSet) {
        funGameView = FunGameFactory.createFunGameView(mContext, attrSet, headerType);
        setHeaderLodingStr(loadingText);
        setHeaderLoadingFinishedStr(loadingFinishedText);
        setHeaderGameOverStr(gameOverText);
        funGameView.postStatus(FunGameView.STATUS_GAME_PREPAR);
        addComponent(funGameView);

        curtainReLayout = new DependentLayout(mContext);
        maskReLayout = new DependentLayout(mContext);
        ShapeElement shapeElement = new ShapeElement();
        shapeElement.setRgbColor(RgbColor.fromArgbInt(Color.getIntColor("#3A3A3A")));
        maskReLayout.setBackground(shapeElement);

        topMaskView = createMaskTextView(topMaskViewText, topMaskTextSize, TextAlignment.BOTTOM);
        bottomMaskView = createMaskTextView(bottomMaskViewText, bottomMaskTextSize, TextAlignment.TOP);

        coverMaskView();

        funGameView.setLayoutRefreshedListener(new MeasureListener());

        setEstimateSizeListener(this);
    }

    private Text createMaskTextView(String text, int textSize, int gravity) {
        Text maskTextView = new Text(mContext);
        maskTextView.setTextColor(Color.BLACK);
        maskTextView.setMultipleLine(true);
        ShapeElement shapeElement = new ShapeElement();
        shapeElement.setRgbColor(RgbColor.fromArgbInt(Color.WHITE.getValue()));
        maskTextView.setBackground(shapeElement);
        maskTextView.setTextAlignment(gravity | TextAlignment.HORIZONTAL_CENTER);
        if (textSize < 0) {
            textSize = DEFAULT_TEXT_SIZE;
        }
        maskTextView.setTextSize(textSize);
        maskTextView.setText(text);
        return maskTextView;
    }

    private void coverMaskView() {
        LayoutConfig maskLp = new LayoutConfig(LayoutConfig.MATCH_PARENT, LayoutConfig.MATCH_PARENT);
        maskLp.setMarginTop((int) FunGameView.DIVIDING_LINE_SIZE);
        maskLp.setMarginBottom((int) FunGameView.DIVIDING_LINE_SIZE);
        addComponent(maskReLayout, maskLp);
        addComponent(curtainReLayout, maskLp);
    }


    private class MeasureListener implements LayoutRefreshedListener {
        @Override
        public void onRefreshed(Component component) {
            halfHitBlockHeight = (int) ((funGameView.getHeight() - 2 * FunGameView.DIVIDING_LINE_SIZE) * .5f);
            DependentLayout.LayoutConfig topRelayLayoutParams =
                    new DependentLayout.LayoutConfig(getWidth(), halfHitBlockHeight);
            DependentLayout.LayoutConfig bottomRelayLayoutParams =
                    new DependentLayout.LayoutConfig(getWidth(), halfHitBlockHeight);
            bottomRelayLayoutParams.setMarginTop(halfHitBlockHeight);
            curtainReLayout.removeAllComponents();
            curtainReLayout.addComponent(topMaskView, 0, topRelayLayoutParams);
            curtainReLayout.addComponent(bottomMaskView, 1, bottomRelayLayoutParams);
            funGameView.setLayoutRefreshedListener(null);
        }
    }

    private void doStart(long delay) {
        AnimatorProperty topMaskAnimator = topMaskView.createAnimatorProperty().moveByY(-halfHitBlockHeight);
        AnimatorProperty bottomMaskAnimator = bottomMaskView.createAnimatorProperty().moveByY(halfHitBlockHeight);
        AnimatorProperty maskShadowAnimator = maskReLayout.createAnimatorProperty().alpha(0);

        AnimatorGroup animatorSet = new AnimatorGroup();
        animatorSet.runParallel(topMaskAnimator, bottomMaskAnimator, maskShadowAnimator);
        animatorSet.setDuration(800);
        animatorSet.setDelay(delay);
        animatorSet.setStateChangedListener(new Animator.StateChangedListener() {
            @Override
            public void onStart(Animator animator) {
            }

            @Override
            public void onStop(Animator animator) {
            }

            @Override
            public void onCancel(Animator animator) {
            }

            @Override
            public void onEnd(Animator animator) {
                topMaskView.setVisibility(Component.HIDE);
                bottomMaskView.setVisibility(Component.HIDE);
                maskReLayout.setVisibility(Component.HIDE);
                funGameView.postStatus(FunGameView.STATUS_GAME_PLAY);
            }

            @Override
            public void onPause(Animator animator) {
            }

            @Override
            public void onResume(Animator animator) {
            }
        });
        animatorSet.start();
    }

    @Override
    public boolean onEstimateSize(int widthMeasureSpec, int heightMeasureSpec) {
        final int heightMode = EstimateSpec.getMode(heightMeasureSpec);
        int widthMode = EstimateSpec.getMode(widthMeasureSpec);
        int width = 0;
        int height = 0;

        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            Component childView = getComponentAt(i);
            ComponentContainer.LayoutConfig layoutConfig = childView.getLayoutConfig();
            widthMeasureSpec = EstimateSpec.getSizeWithMode(layoutConfig.width, widthMode);
            heightMeasureSpec = EstimateSpec.getSizeWithMode(layoutConfig.height, heightMode);
            childView.estimateSize(widthMeasureSpec, heightMeasureSpec);
            if (childView instanceof FunGameView) {
                width = childView.getEstimatedWidth();
                height = childView.getEstimatedHeight();
            }
        }
        if (heightMode == EstimateSpec.UNCONSTRAINT || heightMode == EstimateSpec.PRECISE) {
            widthMeasureSpec = EstimateSpec.getSizeWithMode(width, EstimateSpec.PRECISE);
            heightMeasureSpec = EstimateSpec.getSizeWithMode(height, EstimateSpec.PRECISE);
        }
        setEstimatedSize(widthMeasureSpec, heightMeasureSpec);
        return true;
    }

    /**
     * 游戏开始
     */
    public void postStart() {
        if (!isStart) {
            doStart(200);
            isStart = true;
        }
    }

    /**
     * 游戏结束
     */
    public void postEnd() {
        isStart = false;
        funGameView.postStatus(FunGameView.STATUS_GAME_PREPAR);
        topMaskView.setContentPositionY(0);
        bottomMaskView.setContentPositionY(halfHitBlockHeight);
        maskReLayout.setAlpha(1.0f);

        topMaskView.setVisibility(Component.VISIBLE);
        bottomMaskView.setVisibility(Component.VISIBLE);
        maskReLayout.setVisibility(Component.VISIBLE);
    }

    /**
     * 刷新结束，游戏完成
     */
    public void postComplete() {
        funGameView.postStatus(FunGameView.STATUS_GAME_FINISHED);
    }

    /**
     * 移动控制器
     *
     * @param distance 移动的距离
     */
    public void moveRacket(float distance) {
        if (isStart) {
            funGameView.moveController(distance);
        }
    }

    /**
     * 移动控制器到起点位置
     *
     * @param duration 移动需要的时间
     */
    public void back2StartPoint(long duration) {
        funGameView.moveController2StartPoint(duration);
    }

    /**
     * 获取游戏状态
     *
     * @return 游戏状态
     */
    public int getGameStatus() {
        return funGameView.getCurrStatus();
    }

    /**
     * 设置上边帷幕中的文字
     *
     * @param topMaskViewText 文字内容
     */
    public void setTopMaskViewText(String topMaskViewText) {
        this.topMaskViewText = topMaskViewText;
        topMaskView.setText(topMaskViewText);
    }

    /**
     * 设置下边帷幕中的文字
     *
     * @param bottomMaskViewText 文字内容
     */
    public void setBottomMaskViewText(String bottomMaskViewText) {
        this.bottomMaskViewText = bottomMaskViewText;
        bottomMaskView.setText(bottomMaskViewText);
    }

    /**
     * 加载时的文字
     *
     * @param loadingStr 文字内容
     */
    public void setHeaderLodingStr(String loadingStr) {
        funGameView.setTextLoading(loadingStr);
    }

    /**
     * 游戏结束的文字
     *
     * @param gameOverStr 文字内容
     */
    public void setHeaderGameOverStr(String gameOverStr) {
        funGameView.setTextGameOver(gameOverStr);
    }

    /**
     * 加载结束的文字
     *
     * @param loadingFinishedStr 文字内容
     */
    public void setHeaderLoadingFinishedStr(String loadingFinishedStr) {
        funGameView.setTextLoadingFinished(loadingFinishedStr);
    }

    public String getHeaderLodingStr() {
        return funGameView.getTextLoading();
    }

    public String getHeaderGameOverStr() {
        return funGameView.getTextGameOver();
    }

    public String getHeaderLoadingFinishedStr() {
        return funGameView.getTextLoadingFinished();
    }


}
